"use strict";
// 表示独一无二的值
// 1. symbol数据类型是通过Symbol()函数创建的，接受字符串作为symbol的描述，要是为了在控制台显示，或者转为字符串时，比较容易分清到底是哪一个值
var str1 = Symbol('hello symbol');
var str2 = Symbol('hello symbol');
var str3 = 'hello symbol'
var str4 = 'hello symbol'
console.log(str1 == str2, str1 === str2); // false false
console.log(str3 == str4, str3 === str4); // true true

// 2. 对象的属性名现在可以有两种类型，一种是原来就有的字符串，另一种就是新增的 Symbol 类型。Symbol 值作为对象属性名时，不能用点运算符。
var key1 = 'name'
var key2 = Symbol('age')
var obj1 = { id: 1, [key1]: '马超', [key2]: 12}
console.log(obj1); // {name: "马超", Symbol(age): 12}
console.log(obj1.key2); // undefined
console.log(obj1[key2]); // 12
console.log(obj1['key2']); // undefined
console.log(obj1['id']); // 1

// 3. 如果 Symbol 的参数是一个对象，就会调用该对象的toString方法，将其转为字符串，然后才生成一个 Symbol 值。
var obj2 = { name: '马可波罗', age: 20 }
var obj3 = { name: '蒙犽', age: 15 }
console.log(Symbol(obj2)); // Symbol([object Object])
console.log(Symbol(obj3)); // Symbol([object Object])
// 此时分不清是谁的打印结果，因此重写一个toString方法
var obj4 = {
  name: '嫦娥',
  age: 18,
  toString: function() {
    return `我是${this.name}，今年${this.age}`
  }
}
console.log(Symbol(obj4)); // Symbol(我是嫦娥，今年18) 注意此时的this指向obj4

// 4. Symbol 值可以显式转为字符串
console.log(Symbol(obj4).toString()); // 'Symbol(我是嫦娥，今年18)' 

// 5. Symbol 值也可以转为布尔值，但是不能转为数值。
console.log(Boolean(obj4)); // true
console.log(Number(obj4)); // NaN

// 6. Symbol.prototype.description 获取描述
console.log(Symbol(obj4).description); // '我是嫦娥，今年18'

var data = { id: 1, msg: '来玩生存游戏吧!很酷的!你来出演~生无可恋'}
Object.defineProperty(data, 'msg', {
  get() {
    return '获取了msg的值'
  },
  set(value) {
    console.log('设置了msg的值', value);
  }
})
console.log(data.msg);

data.msg = 123

// 7. Object.getOwnPropertySymbols()方法，可以获取指定对象的所有 Symbol 属性名。
var gender = 'gen'
var obj5 = { id: 5, [Symbol('name')]: '张良', age: 22, [gender + 'der']: '男' }
console.log(obj5, obj5['age']); // { id: 5, age: 22, gender: "男", Symbol(name): "张良" } 22
console.log(Object.keys(obj5)); // ["id", "age", "gender"]
var names = Object.getOwnPropertySymbols(obj5)
console.log(names); // [Symbol(name)]

// 8. Reflect.ownKeys() 返回所有类型的键名，包括常规键名和 Symbol 键名。
console.log(Reflect.ownKeys(obj5)); // ["id", "age", "gender", Symbol(name)]

